package com.wzh.oj.judge.strategy;

import cn.hutool.json.JSONUtil;
import com.wzh.oj.judge.codesandbox.model.JudgeContext;
import com.wzh.oj.judge.codesandbox.model.JudgeInfo;
import com.wzh.oj.model.dto.question.JudgeCase;
import com.wzh.oj.model.dto.question.JudgeConfig;
import com.wzh.oj.model.entity.Question;
import com.wzh.oj.model.enums.JudgeInfoMessageEnum;

import java.util.List;

/**
 * @author wzh
 * java编程语言判题策略
 */
public class JavaLanguageJudgeStrategy implements JudgeStrategy{

    private long JAVA_PROGRAM_TIME_COST=10000L;

    @Override
    public JudgeInfo doJudge(JudgeContext judgeContext) {

        JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
        List<String> inputList = judgeContext.getInputList();
        List<String> outputList = judgeContext.getOutputList();
        Question question = judgeContext.getQuestion();
        List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
//                声明并创需要返回的结果
        JudgeInfo judgeInfoRes=new JudgeInfo();
        JudgeInfoMessageEnum judgeInfoMessageEnum=JudgeInfoMessageEnum.ACCEPTED;
        if (inputList.size()!=outputList.size()){
            judgeInfoMessageEnum=JudgeInfoMessageEnum.WRONG_ANSWER;
              return fail(judgeInfoRes,judgeInfoMessageEnum.getValue());
        }
//            校验实际输出结果和预期输出结果
        for (int i = 0; i < outputList.size(); i++) {
            JudgeCase judgeCase = judgeCaseList.get(i);
            if (!outputList.get(i).equals(judgeCase.getOutput())){
                judgeInfoMessageEnum=JudgeInfoMessageEnum.WRONG_ANSWER;
                return fail(judgeInfoRes,judgeInfoMessageEnum.getValue());
            }
        }

//        校验题目的限制是否符合要求
        Long actualMemory = judgeInfo.getMemory();
        Long actualTime = judgeInfo.getTime();

//        预期时间
        String judgeConfig = question.getJudgeConfig();
        JudgeConfig judgeConfigs = JSONUtil.toBean(judgeConfig, JudgeConfig.class);
        Long memoryLimit = judgeConfigs.getMemoryLimit();
        Long timeLimit = judgeConfigs.getTimeLimit();
//        校验
        if (!timeCheck(actualTime-JAVA_PROGRAM_TIME_COST,timeLimit)){
            judgeInfoMessageEnum=JudgeInfoMessageEnum.OUTPUT_LIMIT_EXCEEDED;
            return fail(judgeInfoRes,judgeInfoMessageEnum.getValue());
        }

        if (!memoryCheck(actualMemory,memoryLimit)){
            judgeInfoMessageEnum=JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;
            return fail(judgeInfoRes,judgeInfoMessageEnum.getValue());
        }
        judgeInfoRes.setMessage(judgeInfoMessageEnum.getValue());
        return judgeInfoRes;
    }

    public JudgeInfo fail(JudgeInfo judgeInfo,String message){
        judgeInfo.setMessage(message);
        return judgeInfo;
    }

    public boolean timeCheck(Long actualTime, Long timeLimit){
            if (actualTime>timeLimit){
                return false;
            }
            return true;
    }

    public boolean memoryCheck(Long actualMemory, Long memoryLimit){
        if (actualMemory>memoryLimit){
            return false;
        }
        return true;
    }
}
